package com.winit.generator.handler.impl;

import com.winit.generator.Constants;
import com.winit.generator.config.Configuration;
import com.winit.generator.handler.BaseHandler;
import com.winit.generator.model.MapperInfo;

import java.io.File;
import java.util.Map;
import java.util.Map.Entry;

public class MapperHandler extends BaseHandler<MapperInfo> {

    public MapperHandler(String ftlName, MapperInfo info) {
        this.ftlName = ftlName;
        this.info = info;
        this.savePath = Configuration.getString("base.baseDir") + File.separator
                + Configuration.getString("mapperXml.path") + File.separator + info.getFileName()
                + Constants.FILE_SUFFIX_XML;

    }

    @SuppressWarnings("unchecked")
    @Override
    public void combileParams(MapperInfo info) {
        // <result column="SU_ROUTE_CODE" jdbcType="VARCHAR"
        // property="suRouteCode" />
        this.param.put("namespace", info.getNamespace());
        this.param.put("entityType", info.getEntityInfo().getPackageClassName());
        this.param.put("tableName", info.getEntityInfo().getTableName());
        this.param.put("tableNameUpper", this.param.get("tableName").toUpperCase());
        this.param.put("entityName", info.getEntityInfo().getEntityName() + "Entity");
        this.param.put("packageStr", info.getEntityInfo().getEntityPackage());
        this.param.put("filterPackageStr", info.getEntityInfo().getFilterPackage());
        this.param.put("filterName", info.getEntityInfo().getFilterName());
        this.param.put("resultName", info.getEntityInfo().getResultName());

        // 基本字段
        StringBuilder resultMap = new StringBuilder();
        StringBuilder allColumn = new StringBuilder();

        // 插入相关字段
        StringBuilder addProperty = new StringBuilder();
        StringBuilder addValue = new StringBuilder();
        StringBuilder batchAddValue = new StringBuilder();

        // 更新相关字段
        StringBuilder updateColProps = new StringBuilder();
        StringBuilder updateBatchColProps = new StringBuilder();

        // 条件查询相关字段
        StringBuilder findListCondition = new StringBuilder();

        // 需要的相关字段
        StringBuilder needColumnCondition = new StringBuilder();

        needColumnCondition.append("        <choose>");


        // 字段对应属性名称
        Map<String, String> propTypes = info.getEntityInfo().getPropTypes();

        for (Entry<String, String> entry : info.getEntityInfo().getPropNameColumnNames().entrySet()) {
            String propName = entry.getKey();
            String columnName = entry.getValue();

            // resultMap
            resultMap.append("        <result column=\"")
                    .append(columnName)
                    /*.append("\" jdbcType=\"")
                    .append(propJdbcTypes.get(propName))*/
                    .append("\" property=\"")
                    .append(propName)
                    .append("\" />\r\n");

            // baseColumn
            allColumn.append(columnName).append(",");

            // addProperty
            if (!"gmt_create".equals(columnName) && !"gmt_modified".equals(columnName)) {
                addProperty.append(columnName).append(",");
                addValue.append("#{").append(propName).append("},");
                if ("member_id".equals(columnName)) {
                    batchAddValue.append("%{memberId},");
                } else if ("member_name".equals(columnName)) {
                    batchAddValue.append("'%{memberName}',");
                } else {
                    batchAddValue.append("#{item.").append(propName).append("},");
                }
            }

            if (!"gmt_create".equals(columnName) && !"gmt_modified".equals(columnName)
                    && !"id".equals(columnName) && !"member_id".equals(columnName)
                    && !"member_no".equals(columnName) && !"member_name".equals(columnName)) {
                // updateColProps
                updateColProps.append("            <if test=\"entity.")
                        .append(propName)
                        .append(" != null\">\r\n                ")
                        .append(columnName)
                        .append("=#{entity.")
                        .append(propName)
                        .append("},\r\n")
                        .append("            </if>\r\n");

                // updateBatchColProps
                updateBatchColProps.append("            <if test=\"item.")
                        .append(propName)
                        .append(" != null\">\r\n                ")
                        .append(columnName)
                        .append("=#{item.")
                        .append(propName)
                        .append("},\r\n")
                        .append("            </if>\r\n");


            }

            // findListCondition - 根据字段不同的类型做不同的筛选
            if (!"gmt_modified".equals(columnName)
                    && !"member_id".equals(columnName)
                    && !"member_no".equals(columnName)) {

                String propType = propTypes.get(propName);
                if ("BigDecimal".equals(propType)) {
                    findListCondition
                            .append("        <if test=\"filter.")
                            .append(propName)
                            .append(" != null\">\r\n            <choose>")

                            // =
                            .append("\r\n                <when test=\"filter.")
                            .append(propName).append("Symbol == '='.toString()\">")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ = ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </when>")

                            // >=
                            .append("\r\n                <when test=\"filter.")
                            .append(propName).append("Symbol == '&gt;='.toString()\">")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ >= ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </when>")

                            // <=
                            .append("\r\n                <when test=\"filter.")
                            .append(propName).append("Symbol == '&lt;='.toString()\">")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ <= ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </when>")

                            // >
                            .append("\r\n                <when test=\"filter.")
                            .append(propName).append("Symbol == '&gt;'.toString()\">")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ > ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </when>")

                            // <
                            .append("\r\n                <when test=\"filter.")
                            .append(propName).append("Symbol == '&lt;'.toString()\">")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ < ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </when>")

                            //otherwise
                            .append("\r\n                <otherwise>")
                            .append("\r\n                    and ")
                            .append(columnName).append(" <![CDATA[ = ]]> ")
                            .append("#{filter.").append(propName).append("}")
                            .append("\r\n                </otherwise>")

                            .append("\r\n            </choose>")
                            .append("\r\n        </if>\r\n");

                } else if ("String".equals(propType)) {

                    findListCondition.append("        <if test=\"filter.")
                            .append(propName)
                            .append(" != null\">\r\n            and ")
                            .append(columnName)
                            .append(" like concat(#{filter.")
                            .append(propName)
                            .append("}, \"%\")\r\n")
                            .append("        </if>\r\n");

                } else if ("Date".equals(propType)) {
                    findListCondition
                            // Start
                            .append("        <if test=\"filter.")
                            .append(propName).append("Begin")
                            .append(" != null\">\r\n            and ")
                            .append(columnName)
                            .append(" <![CDATA[ >= ]]> #{filter.")
                            .append(propName).append("Begin")
                            .append("}\r\n")
                            .append("        </if>\r\n")

                            // End
                            .append("        <if test=\"filter.")
                            .append(propName).append("End")
                            .append(" != null\">\r\n            and ")
                            .append(columnName)
                            .append(" <![CDATA[ <= ]]> #{filter.")
                            .append(propName).append("End")
                            .append("}\r\n")
                            .append("        </if>\r\n")

                    ;
                } else if ("id".equals(columnName)) {

                    findListCondition.append("        <if test=\"filter.")
                            .append(propName)
                            .append(" != null\">\r\n            and ")
                            .append(columnName)
                            .append(" = #{filter.")
                            .append(propName)
                            .append("}\r\n")
                            .append("        </if>\r\n")
                            // 添加ids，foreach统统不要换行
                            .append("        <if test=\"filter.")
                            .append(propName).append("s")
                            .append(" != null and ").append("filter.").append(propName).append("s").append(".length > 0")
                            .append("\">\r\n            and ")
                            .append(columnName)
                            .append(" in")
                            .append("\r\n            <foreach collection=\"filter.").append(propName).append("s").append("\" item=\"item\" open=\"(\" separator=\",\" close=\")\">")
                            .append("#{item}")
                            .append("</foreach>")
                            .append("\r\n        </if>\r\n");

                } else {

                    findListCondition.append("        <if test=\"filter.")
                            .append(propName)
                            .append(" != null\">\r\n            and ")
                            .append(columnName)
                            .append(" = #{filter.")
                            .append(propName)
                            .append("}\r\n")
                            .append("        </if>\r\n");

                }
            }

            needColumnCondition
                    .append("\r\n            <when test=\"item == '")
                    .append(propName).append("'.toString()\">")
                    .append("\r\n                ")
                    .append(columnName).append(",")
                    .append("\r\n            </when>");

        }

        needColumnCondition.append("\r\n            <otherwise>")
               .append("\r\n                id,")
                .append("\r\n            </otherwise>");
        //otherwise
        needColumnCondition.append("\r\n        </choose>");


        this.param.put("resultMap", resultMap.substring(0, resultMap.length() - 2));
        this.param.put("allColumn", allColumn.substring(0, allColumn.length() - 1));

        this.param.put("updateColProps", updateColProps.substring(0, updateColProps.length() - 2));
        this.param.put("updateBatchColProps", updateBatchColProps.substring(0, updateBatchColProps.length() - 2));

        this.param.put("addProperty", addProperty.substring(0, addProperty.length() - 1));
        this.param.put("addValue", addValue.substring(0, addValue.length() - 1));
        this.param.put("batchAddValue", batchAddValue.substring(0, batchAddValue.length() - 1));

        this.param.put("findListCondition", findListCondition.substring(0, findListCondition.length() - 2));

        this.param.put("needColumnCondition", needColumnCondition.substring(0, needColumnCondition.length()));
    }

}
